//headers 
#include<algorithm>
#include<cassert>
#include<cstdio>
#include<deque>
#include<iostream>
#include<list>
#include<map>
#include<numeric>
#include<deque>
#include<set>
#include<string>
#include<sstream>
#include<stack>
#include<streambuf>
#include<vector>
using namespace std;

//macros
#define LET(x,a) typeof(a) x(a)
#define FOR(i,a,n) for(LET(i,a);i!=n;i++)
#define REP(i,n) FOR(i,0,n)
#define sz size()
#define pb push_back
#define ALL(x) x.begin(),x.end()
#define dbge(x) cout<<#x<<"->"<<x<<endl;
#define PRINT(x) REP(_,x.sz) cout<<x[_]<<" "; cout<<endl;
#define OUT(x) x<<" "
const int INF = (int) 1e8;
#define VI vector<int>
#define VS vector<string>
#define VVI vector< vector<int> >
#define LL long long

//code of suren

struct ch {
  char a;
  int times;
  ch() { times=0; }
  
};

bool cmp(struct ch a , struct ch b){
  if(a.times!=b.times) return a.times > b.times;
  else return a.a < b.a;
}


int main(){
  int n; vector<struct ch> a(26);
  REP(i,26) a[i].a='A'+i; string s;
  while(getline(cin,s)){
    REP(i,s.sz) 
      if(s[i]>='a' && s[i]<='z') a[s[i]-'a'].times++;
      else if(s[i]>='A' && s[i]<='Z') a[s[i]-'A'].times++; 
  }
  sort(ALL(a),cmp);  //reverse(ALL(a));
  REP(i,a.sz) if(a[i].times) cout<<a[i].a<<" "<<a[i].times<<endl;

  return 0;
}
